package com.bky.aop;

import com.bky.config.LoginContext;
import com.bky.model.OperateLog;
import com.bky.model.User;
import com.bky.service.OperateLogService;
import com.bky.util.JsonUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.UUID;

/**
 * @Author shipeilei
 * @Date Created on 2018/5/4
 */
@Component
@Aspect
public class SystemLogAspect {
    private static final Logger LOGGER = LoggerFactory.getLogger("SystemLogAspect");
    @Autowired
    private OperateLogService operateLogService;
    /**
     * Service层切点
     */
    @Pointcut("@annotation(com.bky.aop.SystemServiceLog)")
    public void serviceAspect() {}

    /**
     * doServiceLog:获取注解参数，记录日志
     *
     * @param joinPoint 切入点参数
     * java.lang.Object[] getArgs()：获取连接点方法运行时的入参列表
     * Signature getSignature() ：获取连接点的方法签名对象
     * java.lang.Object getTarget() ：获取连接点所在的目标对象
     * java.lang.Object getThis() ：获取代理对象本身
     */
    @AfterReturning(pointcut = "serviceAspect()", returning = "result")
    public void doServiceLog(JoinPoint joinPoint, Object result) {
        User user = LoginContext.getUser();
        if (null == user){
            return;
        }
        try {
            OperateLog log = new OperateLog();
            String methodName = joinPoint.getSignature().getName();
            Class<?> clazz = joinPoint.getTarget().getClass();
            Object[] args = joinPoint.getArgs();
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                if (method.getName().equals(methodName)) {
                    Class<?>[] types = method.getParameterTypes();
                    if (args.length == types.length){
                        SystemServiceLog annotation = method.getAnnotation(SystemServiceLog.class);
                        String description = annotation.description();
                        String tableName = annotation.tableName();
                        log.setId(UUID.randomUUID().toString());
                        log.setContent(JsonUtil.obj2String(joinPoint.getArgs()));
                        log.setDbName(tableName);
                        log.setAction(description);
                        log.setPin(user.getUserName());
                        log.setResult(result.toString());
                        operateLogService.save(log);
                    }

                }
            }
        }catch (Exception e){
            LOGGER.error("插入操作日志失败，用户名：{}", user.getUserName(), e);
        }
    }
}
